#include "LevelManager.h"

#include "Logger.h"
#include "Player.h"
#include "Singleton.h"

LevelManager LevelManager::instance;
bool LevelManager::initialised = false;

void LevelManager::initialise(std::string levelId, PlayerPtr player)
{
    BEGIN_INITIALISATION("LevelManager");

    instance.readFile(levelId, player);
    
    END_INITIALISATION("LevelManager");
}

void LevelManager::cleanUp()
{
    BEGIN_CLEAN_UP("LevelManager");

    instance = LevelManager();
    //instance.unregister_All();

    END_CLEAN_UP("LevelManager");
}

bool LevelManager::isInitialised()
{
    return initialised;
}

LevelManager& LevelManager::get()
{
	GET_INSTANCE("LevelManager");
}

LevelManager::LevelManager()
: baseRenderDepth(0)
, fadeWaiting(false)
{
}

LevelManager::~LevelManager()
{
}

// void LevelManager::loadStartLevel()
// {
//     teleportPlayer(Portal(startLevelFn.string(), sf::Vector2f(), playerStartPos));
// }

LevelPtr LevelManager::getCurrentLevel() const
{
	return currentLevel;
}

//CameraPtr LevelManager::getCamera() const
//{
//	return levelCamera;
//}

bool LevelManager::isLevelLoading() const
{
    return 0;//changedLevelsFade.isFading();
}

void LevelManager::teleportPlayer(const Portal& portal)
{
    if(currentLevel)
    {
        //currentLevel->Teleport(*player, portal);
    }
}

void LevelManager::update(float delta)
{
    //if(changedLevelsFade.isFading())
    //{ // Fade is still fading.
    //    if(changedLevelsFade.Update(delta))
    //    { // Still fading...        
    //        if(!portalHit.toLevel().empty() && changedLevelsFade.Is_Stalling())
    //        { // We just finished fading out and haven't yet loaded the hit level.
    //          // Now we'll stall so that we can load it.
    //            // We load the level while the screen is black (fade is stalled)
    //            // as a kind of implicit waiting screen... the total time the screen is
    //            // black will be the stall duration plus the time it takes to load the level.
    //            toLevel.reset(new Level(gameDir / portalHit.toLevel(), levelCamera));
    //            //notifyListenersIntermission(LevelPtr() == currentLevel, *toLevel, portalHit.toPos());
    //            currentLevel = toLevel;
    //            currentLevel->register(this);
    //            currentLevel->onPlayerEnter(player);
    //            toLevel.reset();
    //            // Set this so that we only stall once!
    //            portalHit = Portal();
    //        }
    //    }
    //    else
    //    { // Finished fading.
    //        NotifyListenersFinished();
    //    }
    //}

    if(currentLevel) currentLevel->update(delta);
}

void LevelManager::render(sf::RenderWindow& renderer)
{
     if(currentLevel) currentLevel->render(renderer);
    /*if(fadeWaiting)
    {       
        renderer.Fade(changedLevelsFade);
        fadeWaiting = false;
    }

    if(currentLevel && !changedLevelsFade.Is_Stalling())
    {
        currentLevel->Render(renderer, TILE_AT(0));
    }*/
}

void LevelManager::readFile(std::string levelId, PlayerPtr player)
{
    currentLevel.reset(new Level());
}

void LevelManager::writeFile(std::string levelId) const
{
}

//ushort LevelManager::getBaseDepth() const
//{
//    return baseRenderDepth;
//}

void LevelManager::setCurrentLevel()
{
	//if(std::find_if(levels.begin(), levels.end(),
 //   Pair_First_Equal<level_map::value_type, std::string>(name)) == levels.end())
 //   { // Haven't loaded this level yet; load it.
 //       Level level;
 //       loadLevel(level, name);
 //   }

	//currentLevel = &levels[name];
 //   currentLevel->onPlayerEntered();
	//changed_levels = true;
}